<?php
/**
 * PHP Scripts Specific Exceptions
 * 
 *  @author polux
 *  @version 1.0
 */

// ------------------------------------------------------------------------------------------------------------- //

/**
 * MainException - Main root class
 * 
 * @author polux
 *
 */
abstract class MainException extends Exception
{
	// ******************************** Static Attributes ******************************** //
	/**
	 * Unique ID Table
	 *
	 * @var array(string=>integer)
	 */
	protected static $_ai_uniqueID=array();
	
	// ******************************** Dynamic Attributes ******************************** //
	/**
	 * Type of Exception
	 *
	 * @var string
	 */
	protected $_s_type;
	/**
	 * Unique ID 
	 *
	 * @var string
	 */
	protected $_s_internalID;
	/**
	  * Timestamp of exception
	  *
	  * @var long
	  */
	protected $_l_timestamp;
	/**
	 * Root message of exception
	 *
	 * @var string
	 * @access protected
	 */
	protected $_s_msg;
	
	// ******************************** Default Builder ******************************** //
	/**
	 * Class default builder
	 * 
	 * @param string $p_s_message
	 * @param string $p_s_code
	 * @param string $p_s_previous
	 */
	function __construct($p_s_type,$p_s_message=null,$p_s_code=null,$p_s_previous=null)
	{
		// Local attributes first
		$this->_s_msg = $p_s_message;
		$this->_s_type = $p_s_type;
		$this->_s_internalID = MainException::getUniqueIDByExceptionType($p_s_type);
		$this->_l_timestamp = time();	
		$l_s_msg = $this->getExceptionSpecificMessage();
		
		// Parent builder
		parent::__construct($l_s_msg,$p_s_code,$p_s_previous);
	}
	
	// ******************************** Public Methods ******************************** //
	/**
	 * getUniqueID - Returns Unique ID of this exception
	 * 
	 * @return string
	 */
	public function getUniqueID()
	{
		return $this->_s_internalID;
	}
	
	// ******************************** Static Methods ******************************** //
	/**
	 * getUniqueIDByExceptionType - Retrun a string represzenting UniqueId of Exception by type
	 * 
	 * @param string 	$p_s_type	Type Exception code
	 * @return string
	 * 
	 * @example getUniqueIDByExceptionType(EXCEPTION_TYPE_LOG_INTERNAL) => "01"
	 */
	protected static function getUniqueIDByExceptionType($p_s_type)
	{
		$l_i_uniqueID = 0;
		
		// Type exist in array
		if(!is_null($p_s_type) && array_key_exists($p_s_type, MainException::$_ai_uniqueID))
		{
			$l_i_uniqueID = MainException::$_ai_uniqueID[$p_s_type];
			MainException::$_ai_uniqueID[$p_s_type]++;
		}
		elseif (!is_null($p_s_type))
		{
			MainException::$_ai_uniqueID[$p_s_type] = 1;
			$l_i_uniqueID = 1;
		}
		else 
		{
			throw new Exception("getUniqueIDByExceptionType : type parameter null !!");
		}
		
		return sprintf('%03d',$l_i_uniqueID);		
	}

	/**
	 * getExceptionSpecificMessage - Format wish in sub-classe about layout of message
	 * 
	 * @abstract
	 * @return string 
	 */
	abstract function getExceptionSpecificMessage();

}

// ------------------------------------------------------------------------------------------------------------- //

/**
 * JobRootException - Root Exception class for all Job related seceptions
 * 
 * @author polux
 * @uses MainException
 */
class JobRootException extends MainException
{
	// ******************************** Constructor ******************************** //
	/**
	 * Default constructor
	 * 
	 * @param string 	$p_s_typeofException	Type of exception
	 * @param string 	$p_s_msg				Root msg of exception
	 * @link global_constants.php
	 */
	public function __construct($p_s_typeofException,$p_s_msg) 
	{		
		// Parent
		parent::__construct($p_s_typeofException,$p_s_msg);		
	}
	
	// ********************************  Methods  ******************************** //
	/**
	 * getExceptionSpecificMessage - Default displaying for this exception.
	 * 
	 * @return string
	 * @see MainException::getExceptionSpecificMessage()
	 */
	function getExceptionSpecificMessage()
	{
		return sprintf("EXCEPT-[ %s ]-( JOB )|{%s}- %s",date("Y m d_h:i:s",$this->_l_timestamp),$this->getUniqueID(),$this->_s_msg);
		// TODO REV2 => type Interfaces (critiques, medium, info ... ?) à réfléchir
	}	
	
}

/**
 * JobNotFoundException - Exception Class
 * 
 * @author polux
 * 
 */
class JobNotFoundException extends JobRootException implements IExceptionCritical 
{
	// ******************************** Properties ******************************** //
	/**
	 * JobName which is the root cause of Exception
	 * @var string
	 */
	protected $_s_JobNameConcerned = null;
	
	// ******************************** Constructor ******************************** //
	/**
	 * Default constructor
	 * 
	 * @param string $p_s_NotFoundedJobName
	 */
	public function __construct($p_s_NotFoundedJobName)
	{
		global $EXCEPTION_MSGS;
		$this->_s_JobNameConcerned = $p_s_NotFoundedJobName;
		
		$l_s_msg = sprintf($EXCEPTION_MSGS[EXCEPTION_TYPE_JOB_FILE_NOTFOUND],$p_s_NotFoundedJobName);
		
		// Defining type of Exception & message
		parent::__construct(EXCEPTION_TYPE_JOB_FILE_NOTFOUND,$l_s_msg);		
	}
	
	public function CriticalMessage()
	{
		return "CRIT";
	}
}

/**
 * JobGenericException - Exception Class
 *
 * @author polux
 *
 */
class JobGenericException extends JobRootException {
	// ******************************** Constructor ******************************** //
	/**
	 * Default constructor
	 *
	 * @param string $p_s_NotFoundedJobName
	 */
	public function __construct($p_s_msg)
	{
		// Defining type of Exception & message
		parent::__construct(EXCEPTION_TYPE_JOB_GENERIC,$p_s_msg);
	}
}


/**
 * JobParameterFoundException - Exception Class
 *
 * @author polux
 *
 */
class JobParameterFoundException extends JobRootException implements IExceptionCritical 
{
	// ******************************** Attributes ******************************** //
	/**
	 * JobName 
	 * @var string
	 */
	protected $_s_JobNameConcerned = null;	
	/**
	 * Parameter name which is the root cause of Exception
	 * @var string
	 */
	protected $_s_ParameterNameConcerned = null;

	// ******************************** Constructor ******************************** //
	/**
	 * Default constructor
	 *
	 * @param string $p_s_NotFoundedJobName
	 */
	public function __construct($p_s_parameterNotFound,$p_s_JobName)
	{
		global $EXCEPTION_MSGS;
		$this->_s_JobNameConcerned = $p_s_JobName;
		$this->_s_ParameterNameConcerned = $p_s_parameterNotFound;
		$l_s_msg = sprintf($EXCEPTION_MSGS[EXCEPTION_TYPE_JOB_PARAM_NOTFOUND],$p_s_parameterNotFound,$p_s_JobName);

		// Defining type of Exception & message
		parent::__construct(EXCEPTION_TYPE_JOB_PARAM_NOTFOUND,$l_s_msg);
	}

	public function CriticalMessage()
	{
		return "CRIT";
	}
}

// ------------------------------------------------------------------------------------------------------------- //

/**
 * JobToolRootException - Root class about jobtool exception
 *
 * @author polux
 */
class JobToolRootException extends MainException
{
	/**
	 * Default builder
	 * @param string 	$p_s_typeOfException
	 * @param string 	$p_s_msg
	 */
	public function __construct($p_s_typeOfException,$p_s_msg)
	{
		parent::__construct($p_s_typeOfException,$p_s_msg);
	}

	/**
	 * getExceptionSpecificMessage - Default displaying for this exception.
	 *
	 * @return string
	 * @see MainException::getExceptionSpecificMessage()
	 */
	function getExceptionSpecificMessage()
	{
		return sprintf("EXCEPT-[ %s ]-( JOBTOOL )|{%s}- %s",date("Y m d_h:i:s",$this->_l_timestamp),$this->getUniqueID(),$this->_s_msg);
		// TODO REV2 => type Interfaces (critiques, medium, info ... ?) à réfléchir
	}
}

/**
 * LogStreamAccessException - Exception call about Stream errors
 *
 * @author polux
 */
class JobToolGenericException extends JobToolRootException
{
	/**
	 * Default constructor
	 *
	 * @param string $p_s_msg
	 */
	public function __construct($p_s_msg) {
		// Parent default constructor
		parent::__construct(EXCEPTION_JTOOL_GENERIC,$p_s_msg);
	}
}


// ------------------------------------------------------------------------------------------------------------- //

/**
 * LogRootException - Root class about log exception
 * 
 * @author polux
 */
class LogRootException extends MainException
{	
	/**
	 * Default builder
	 * @param string 	$p_s_typeOfException
	 * @param string 	$p_s_msg
	 */
	public function __construct($p_s_typeOfException,$p_s_msg) 
	{
		parent::__construct($p_s_typeOfException,$p_s_msg);
	}
	
	/**
	 * getExceptionSpecificMessage - Default displaying for this exception.
	 *
	 * @return string
	 * @see MainException::getExceptionSpecificMessage()
	 */
	function getExceptionSpecificMessage()
	{
		return sprintf("EXCEPT-[ %s ]-( LOG )|{%s}- %s",date("Y m d_h:i:s",$this->_l_timestamp),$this->getUniqueID(),$this->_s_msg);
		// TODO REV2 => type Interfaces (critiques, medium, info ... ?) à réfléchir
	}
}

/**
 * LogStreamAccessException - Exception call about Stream errors
 * 
 * @author polux
 */
class LogStreamAccessException extends LogRootException
{
	/**
	 * Default constructor
	 * 
	 * @param string $p_s_msg
	 */
	public function __construct($p_s_msg) {
		// Parent default constructor
		parent::__construct(EXCEPTION_TYPE_LOG_STREAM,$p_s_msg);
	}
}

/**
 * LogStreamAccessException - Generic Exception class
 * 
 * @author polux
 */
class LogGenericException extends LogRootException
{
	/**
	 * Default constructor
	 * 
	 * @param string $p_s_msg
	 */
	public function __construct($p_s_msg) {
		parent::__construct(EXCEPTION_TYPE_LOG_INTERNAL,$p_s_msg);
	}
}

?>